using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;

namespace BookBarter
{
    public class Address
    {
        private static List<Address> addresses = new List<Address>();

        private Guid _ID;
        private String street;
        private String city;
        private String state;

        public Guid ID
        {
            get
            {
                return _ID;
            }
            private set
            {
                _ID = value;
            }
        }
        public String City
        {
            get
            {
                return city;
            }
            set
            {
                city = value;
                Save();
            }
        }
        public String State
        {
            get
            {
                return state;
            }
            set
            {
                state = value;
                Save();
            }
        }
        public String Street
        {
            get
            {
                return street;
            }
            set
            {
                street = value;
                Save();
            }
        }

        private Address(Guid ID, String City, String State, String Street)
        {
            this.ID = ID;
            this.State = State;
            this.City = City;
            this.Street = Street;
        }
        internal static Address CreateAddress(String City, String State, String Street)
        {
            Address newAddress = null;
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;
            SqlCommand query = new SqlCommand("EXEC add_address @street, @city, @state", cnx);
            query.Parameters.Add("@street", System.Data.SqlDbType.VarChar);
            query.Parameters.Add("@city", System.Data.SqlDbType.VarChar);
            query.Parameters.Add("@state", System.Data.SqlDbType.VarChar);
            query.Parameters["@city"].SqlValue = City;
            query.Parameters["@state"].SqlValue = State;
            query.Parameters["@street"].SqlValue = Street;
            SqlDataReader result = query.ExecuteReader();
            try
            {
                if (result.Read())
                {
                    if (result.IsDBNull(result.GetOrdinal("addressid")))
                    {
                        result.Close();
                        throw new MalformedAddressRecord("Value is NULL where there should be an ID.");
                    }
                    newAddress = GetAddress(result.GetGuid(result.GetOrdinal("addressid")));
                }
                else
                {
                    throw new NewAddressException("Failed to create new Address");
                }
            }
            finally
            {
                result.Close();
            }
            addresses.Add(newAddress);
            return newAddress;
        }
        internal static Address GetAddress(Guid ID)
        {
            //searches list of addresses for guid
            foreach (Address a in addresses)
                if (a.ID.Equals(ID))
                    return a;

            //create defaults for variables
            String street = "", city = "", state = "";
            int numPages = 0;

            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;
            //create the query
            SqlCommand query = new SqlCommand("EXEC get_address @addressid", cnx);
            query.Parameters.Add("@addressid");
            query.Parameters["@addressid"].SqlDbType = System.Data.SqlDbType.UniqueIdentifier;
            query.Parameters["@addressid"].SqlValue = ID;

            //execute the query
            SqlDataReader result = query.ExecuteReader();
            try
            {
                //set info
                if (result.Read())
                {
                    street = result["street"].ToString();
                    city = result["city"].ToString();
                    state = result["state"].ToString();

                }
                //else - the book is INVALID
                else
                {
                    throw new NoSuchAddress("The Address does not exist!");
                }
            }
            finally
            {
                result.Close();
            }

            //if we are here... return the book hold object
            Address requestedAddress = new Address(ID, street, city, state);
            addresses.Add(requestedAddress);
            return requestedAddress;
        }
        private void Save()
        {
            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;
            SqlCommand query = new SqlCommand("EXEC update_address @addressid, @street, @city, @state", cnx);
            query.Parameters.Add("@addressid");
            query.Parameters["@addressid"].SqlDbType = System.Data.SqlDbType.UniqueIdentifier;
            query.Parameters["@addressid"].SqlValue = this.ID;

            query.Parameters.Add("@street");
            query.Parameters["@street"].SqlDbType = System.Data.SqlDbType.VarChar;
            query.Parameters["@street"].SqlValue = this.Street;

            query.Parameters.Add("@city");
            query.Parameters["@city"].SqlDbType = System.Data.SqlDbType.VarChar;
            query.Parameters["@city"].SqlValue = this.City;

            query.Parameters.Add("@state");
            query.Parameters["@state"].SqlDbType = System.Data.SqlDbType.VarChar;
            query.Parameters["@state"].SqlValue = this.State;

            query.ExecuteNonQuery();
        }
    }
}
